与题目定义有些不同,表示人数,表示淘汰赛轮数。题目显然输入的是,根据它算出。为了方便2进制计算,编号从~。最后答案加1即可。同时,比赛胜败概率为了方便先除以100,用计算。
现在考虑如何计算答案,设为对的胜率,为第轮胜出的概率。那么有:
当然,必须保证可能在第轮与比赛,我们可以用位运算实现。

我们会发现,在第轮的比赛中,只有二进制下位不同(输了的人不可能和赢的人再比一场),才有可能比赛,用位运算实现就是:
那么,暴力转移即可,最后,统计中的最大值,输出。
#include <cstdio>
#include <cstring>
const int MAXN = 1 << 10;
int n , m, dex;
double f[ 15 ][ MAXN + 5 ] , a[ MAXN + 5 ][ MAXN + 5 ];
int main( ) {
scanf("%d",&m);
n = ( 1 << m ) - 1;
for( int i = 0 ; i <= n ; i ++ )
for( int j = 0 ; j <= n ; j ++ )
scanf("%lf",&a[ i ][ j ]) , a[ i ][ j ] /= 100;
for( int i = 0 ; i <= n ; i += 2 ) {
f[ 1 ][ i ] = a[ i ][ i + 1 ];
f[ 1 ][ i + 1 ] = a[ i + 1 ][ i ];
}
for( int i = 2 ; i <= m ; i ++ )
for( int j = 0 ; j <= n ; j ++ )
for( int k = 0 ; k <= n ; k ++ )
if( ( ( ( j >> ( i - 1 ) ) ^ 1 ) == ( k >> ( i - 1 ) ) ) )
f[ i ][ j ] += f[ i - 1 ][ j ] * f[ i - 1 ][ k ] * a[ j ][ k ];
double Ans = 0;
for( int i = 0 ; i <= n ; i ++ )
if( f[ m ][ i ] > Ans ) Ans = f[ m ][ dex = i ];
printf("%d\n",dex + 1);
return 0;
}